/*****************************************************************************************
   
   Copyright (c) Microsoft Corporation. All rights reserved.

   Use of this code sample is subject to the terms of the Microsoft
   Permissive License, a copy of which should always be distributed with
   this file.  You can also access a copy of this license agreement at:
   http://www.microsoft.com/resources/sharedsource/licensingbasics/permissivelicense.mspx

 ****************************************************************************************/

using System;

namespace GrooveWebServicesV12Helpers.Files
{
	/// <summary>
	/// Represents a Folder in a Groove Files tool.
	/// </summary>
	public class Folder : GrooveWebServicesV12Helpers.Files.FileFolderBase
	{
        public Folder(GrooveWebServicesV12Helpers.Files.FilesTool i_FilesTool, GrooveWebServicesV12Helpers.Files.Folder i_ParentFolder, GrooveFilesWebService.FileDescriptor i_FileDescriptor)
			: base(i_FilesTool, i_ParentFolder, i_FileDescriptor)
		{
		}

		/// <summary>
		/// True if files in the folder will be downloaded automatically.
		/// </summary>
		public bool AutoDownload
		{
			get
			{
				return m_FileDescriptor.AutoDownload;
			}
		}

		/// <summary>
		/// Size limit below which files in the folder will be downloaded automatically.
		/// </summary>
		public int DownloadSizeLimit
		{
			get
			{
				return m_FileDescriptor.DownloadSizeLimit;
			}
		}

		/// <summary>
		/// The number of things in the folder.
		/// </summary>
		public int Count
		{
			get
			{
				return m_FileDescriptor.Count;
			}
		}

		/// <summary>
		/// Get all content of the folder.
		/// </summary>
		/// <param name="o_Folders">Out: array of Folders</param>
		/// <param name="o_Files">Out: array of Files</param>
		/// <param name="i_Recursive">True to search subfolders recursively</param>
		public void GetAllContent(out GrooveWebServicesV12Helpers.Files.Folder[] o_Folders, out GrooveWebServicesV12Helpers.Files.File[] o_Files, bool i_Recursive)
		{
			m_FilesTool.int_GetContent
				(
				this,
				GrooveWebServicesV12Helpers.Files.FilesTool.FilesType.All,
				out o_Folders,
				out o_Files,
				i_Recursive
				);
		}

		/// <summary>
		/// Get an array of the Folders within this Folder.
		/// </summary>
        public GrooveWebServicesV12Helpers.Files.Folder[] Folders
		{
			get
			{
				GrooveWebServicesV12Helpers.Files.Folder[] Folders = null;
				GrooveWebServicesV12Helpers.Files.File[] Files = null;

				//  Get list of folder entries for this tool
				m_FilesTool.int_GetContent
					(
					this,
					GrooveWebServicesV12Helpers.Files.FilesTool.FilesType.Folder,
					out Folders,
					out Files,
					false	// recursive
					);

				return Folders;
			}
		}

		/// <summary>
		/// Get an array of the Files within this Folder.
		/// </summary>
        public GrooveWebServicesV12Helpers.Files.File[] Files
		{
			get
			{
				GrooveWebServicesV12Helpers.Files.Folder[] Folders = null;
				GrooveWebServicesV12Helpers.Files.File[] Files = null;

				//  Get list of file entries for this tool
				m_FilesTool.int_GetContent
					(
					this,
					GrooveWebServicesV12Helpers.Files.FilesTool.FilesType.File,
					out Folders,
					out Files,
					false	// recursive
					);

				return Files;
			}
		}

		/// <summary>
		/// Add a new folder.
		/// </summary>
		/// <param name="i_Name">Name of the folder</param>
		/// <param name="i_DisplayName">Displayname of the folder</param>
		/// <returns>URI of the new folder</returns>
		public string AddFolder(string i_Name, string i_DisplayName)
		{
			return int_Add
				(
				i_Name, 
				i_DisplayName, 
				null
				);
		}

		/// <summary>
		/// Import contents of a folder (including subfolders) from the local disk.
		/// </summary>
		/// <param name="i_SourceFolderPath">Path to the source folder</param>
		/// <returns>URI of the the file or folder that has been created in the Files tool. In the case of a recursive import, the folder is the root of the imported subtree.</returns>
		public string Import(string i_SourceFolderPath)
		{
			string[] SourceFolderPathParts = i_SourceFolderPath.Split(new char[] {'\\', '/'});
			string TargetName = SourceFolderPathParts[SourceFolderPathParts.Length - 1];

			return int_Import
				(
				i_SourceFolderPath,
				TargetName,
				true				//  Recursive
				);
		}

		/// <summary>
		/// Import contents of a folder from the local disk.
		/// </summary>
		/// <param name="i_SourceFolderPath">Path to the source folder</param>
		/// <param name="i_Recursive">True to include subfolders recursively.</param>
		/// <returns>URI of the the file or folder that has been created in the Files tool. In the case of a recursive import, the folder is the root of the imported subtree.</returns>
		public string Import(string i_SourceFolderPath, bool i_Recursive)
		{
			string[] SourceFolderPathParts = i_SourceFolderPath.Split(new char[] {'\\', '/'});
			string TargetName = SourceFolderPathParts[SourceFolderPathParts.Length - 1];

			return int_Import
				(
				i_SourceFolderPath,
				TargetName,
				i_Recursive
				);
		}

		/// <summary>
		/// Import contents of a folder from the local disk.
		/// </summary>
		/// <param name="i_SourceFolderPath">Path to the source folder</param>
		/// <param name="i_TargetName">Name of the target folder</param>
		/// <param name="i_Recursive">True to include subfolders recursively.</param>
		/// <returns>URI of the the file or folder that has been created in the Files tool. In the case of a recursive import, the folder is the root of the imported subtree.</returns>
		public string Import(string i_SourceFolderPath, string i_TargetName, bool i_Recursive)
		{
			return int_Import
				(
				i_SourceFolderPath,
				i_TargetName,
				i_Recursive
				);
		}

		/// <summary>
		/// Remove a folder from this folder.
		/// </summary>
		/// <param name="i_FolderURI">URI of the folder to remove.</param>
		public void RemoveFolder(string i_FolderURI)
		{
			int_Remove(i_FolderURI);
		}

		/// <summary>
		/// Add a new file in this folder.
		/// </summary>
		/// <param name="i_Name">Name of the file</param>
		/// <param name="i_DisplayName">Displayname of the file</param>
		/// <param name="i_FileContents">Byte array with the file contents</param>
		/// <returns>URI of the new file</returns>
		public string AddFile(string i_Name, string i_DisplayName, System.Byte[] i_FileContents)
		{
			//  Make sure valid file contents specified
			if (i_FileContents == null)
				throw new System.ArgumentException("Invalid file contents!");

			return int_Add
				(
				i_Name, 
				i_DisplayName, 
				i_FileContents
				);
		}

		/// <summary>
		/// Open a folder by URI
		/// </summary>
		/// <param name="i_FolderURI">URI of the folder</param>
		/// <returns>Folder</returns>
		public GrooveWebServicesV12Helpers.Files.Folder OpenFolder(string i_FolderURI)
		{
			//  ------------------------------------------------------------------------------------------
			//  HACK ALERT:  No method to specifically open folder, so we must iterate through all folders
			
				GrooveWebServicesV12Helpers.Files.Folder[] Folders = this.Folders;
				foreach (GrooveWebServicesV12Helpers.Files.Folder Folder in Folders)
				{
					if (Folder.URI == i_FolderURI)
						return Folder;
				}

			//  ------------------------------------------------------------------------------------------

			throw new System.Exception("Folder: " + i_FolderURI + " not found!");
		}

		/// <summary>
		/// Open a file by URI
		/// </summary>
		/// <param name="i_FileURI">URI of the file</param>
		/// <returns>File</returns>
		public GrooveWebServicesV12Helpers.Files.File OpenFile(string i_FileURI)
		{
			//  ------------------------------------------------------------------------------------------
			//  HACK ALERT:  No method to specifically open file, so we must iterate through all files
			
				GrooveWebServicesV12Helpers.Files.File[] Files = this.Files;
				foreach (GrooveWebServicesV12Helpers.Files.File File in Files)
				{
					if (File.URI == i_FileURI)
						return File;
				}

			//  ------------------------------------------------------------------------------------------

			throw new System.Exception("File: " + i_FileURI + " not found!");
		}

		/// <summary>
		/// Find folders matching a keyword in their name
		/// </summary>
		/// <param name="i_Keyword">Partial name (case insensitive)</param>
		/// <param name="i_Recursive">True to search subfolders recursively</param>
		/// <returns>Array of Folders</returns>
		public GrooveWebServicesV12Helpers.Files.Folder[] FindMatchingFolders(string i_Keyword, bool i_Recursive)
		{
			return m_FilesTool.int_FindMatchingFolders
				(
				this, 
				i_Keyword, 
				i_Recursive
				);
		}

		/// <summary>
		/// Find files matching a keyword in their name
		/// </summary>
		/// <param name="i_Keyword">Partial name (case insensitive)</param>
		/// <param name="i_Recursive">True to search subfolders recursively</param>
		/// <returns>Array of Files</returns>
		public GrooveWebServicesV12Helpers.Files.File[] FindMatchingFiles(string i_Keyword, bool i_Recursive)
		{
			return m_FilesTool.int_FindMatchingFiles
				(
				this, 
				i_Keyword, 
				i_Recursive
				);
		}

		/// <summary>
		/// Delete a file from this folder.
		/// </summary>
		/// <param name="i_FileURI">URI of the file to delete.</param>
		public void RemoveFile(string i_FileURI)
		{
			int_Remove(i_FileURI);
		}

		/// <summary>
		/// Download the contents of this folder.
		/// </summary>
		/// <param name="i_Recursive">True to include contents of folders within this folder.</param>
		public void Download(bool i_Recursive)
		{
			//  Get initialized reference to web service
			GrooveFilesWebService.GrooveFilesBase64 FilesWebService = GrooveWebServicesV12Helpers.Files.FilesTool.CreateInitializedFilesWebService
				(
				m_IdentityURL,
				this.URI,
				Context
				);

			System.DateTime BeginDateTime = System.DateTime.Now;

			//  Ask service to download
			FilesWebService.Download
				(
				i_Recursive,
				true			// recursive specified
				);

			if (GrooveWebServicesV12Helpers.Context.TraceEnabled)
			{
				System.TimeSpan TimeSpan = System.DateTime.Now.Subtract(BeginDateTime);
				System.Diagnostics.Debug.WriteLine("FilesWebService::Download, " + TimeSpan.TotalMilliseconds + " ms");
			}

		}

		private string int_Add(string i_Name, string i_DisplayName, System.Byte[] i_FileContents)
		{
			//  Get initialized reference to web service
			GrooveFilesWebService.GrooveFilesBase64 FilesWebService = GrooveWebServicesV12Helpers.Files.FilesTool.CreateInitializedFilesWebService
				(
				m_IdentityURL,
				m_FilesTool.Data,
				Context
				);

			//  Set parameters
			GrooveFilesWebService.FileDescriptor FileDescriptor = new GrooveFilesWebService.FileDescriptor();
			FileDescriptor.Name = i_Name;
			FileDescriptor.DisplayName = i_DisplayName;
			FileDescriptor.FolderID = this.ID;

			if (i_FileContents == null)
			{
				FileDescriptor.Type = "Folder";
				i_FileContents = new byte[0];
			}
			else
				FileDescriptor.Type = "File";

			System.DateTime BeginDateTime = System.DateTime.Now;

			//  Ask service to create item
			string ItemURI = FilesWebService.Create(FileDescriptor, i_FileContents);

			if (GrooveWebServicesV12Helpers.Context.TraceEnabled)
			{
				System.TimeSpan TimeSpan = System.DateTime.Now.Subtract(BeginDateTime);
				System.Diagnostics.Debug.WriteLine("FilesWebService::Create, " + TimeSpan.TotalMilliseconds + " ms");
			}

			return ItemURI;
		}

		private string int_Import(string i_SourcePath, string i_TargetName, bool i_Recursive)
		{
			if (!System.IO.Directory.Exists(i_SourcePath) && !System.IO.File.Exists(i_SourcePath))
				throw new System.ArgumentException("Specified path is not valid!");

			//  Get initialized reference to web service
			GrooveFilesWebService.GrooveFilesBase64 FilesWebService = GrooveWebServicesV12Helpers.Files.FilesTool.CreateInitializedFilesWebService
				(
				m_IdentityURL,
				m_FilesTool.Data,
				Context
				);

			//  Set parameters
			GrooveFilesWebService.FileDescriptor FileDescriptor = new GrooveFilesWebService.FileDescriptor();
			FileDescriptor.FolderID = this.ID;
			FileDescriptor.Name = i_TargetName;

			System.DateTime BeginDateTime = System.DateTime.Now;

			//  Ask service to import
			string ItemURI = FilesWebService.Import
				(
				i_SourcePath,
				FileDescriptor,
				i_Recursive
				);

			if (GrooveWebServicesV12Helpers.Context.TraceEnabled)
			{
				System.TimeSpan TimeSpan = System.DateTime.Now.Subtract(BeginDateTime);
				System.Diagnostics.Debug.WriteLine("FilesWebService::Import, " + TimeSpan.TotalMilliseconds + " ms");
			}

			return ItemURI;
		}

		private void int_Remove(string i_TargetURI)
		{
			//  Get initialized reference to web service
			GrooveFilesWebService.GrooveFilesBase64 FilesWebService = GrooveWebServicesV12Helpers.Files.FilesTool.CreateInitializedFilesWebService
				(
				m_IdentityURL,
				i_TargetURI,
				Context
				);

			System.DateTime BeginDateTime = System.DateTime.Now;

			//  Ask service to delete folder
			FilesWebService.DeleteFile();

			if (GrooveWebServicesV12Helpers.Context.TraceEnabled)
			{
				System.TimeSpan TimeSpan = System.DateTime.Now.Subtract(BeginDateTime);
				System.Diagnostics.Debug.WriteLine("FilesWebService::DeleteFile, " + TimeSpan.TotalMilliseconds + " ms");
			}
		}
	}
}
